<?php
class ResourceManager {
	
	private $resourceLoaders;
	private $defaultResourceLoader;
	
	public function __construct() {
		
	}
	
	/**
     * Initialize the ResourceManager.
     */
    public function initialize(GeryEngine $engine) {
    	
    	$this->resourceLoaders = array();
    	
    	$resourceLoaderNames = $engine->getConfiguration()->getArray('resource.loader');
    	
    	foreach ($resourceLoaderNames as $resourceLoaderName) {
    		
    		$loaderID = $resourceLoaderName . ".resource.loader";
    		
    		$loaderConfiguration = 
    			$engine->getConfiguration()->subset($loaderID);
    		
    		if (! $loaderConfiguration->isInitialized()) {
    			$engine->warning("ResourceManager: No configuration information for resource loader named '" . $resourceLoaderName . "'. Skipping.");
    			continue;
    		}
    		
    		$loaderClass = $loaderConfiguration->getString("class");
    		
    		if ($loaderClass == null)
            {
            	$engine->error(  "Unable to find '" . $resourceLoaderName . "'"
                                . ".resource.loader.class' specification in configuation."
                                . " This is a critical value.  Please adjust configuration.");
				continue;
            }
            
			$resourceLoader = ResourceLoaderFactory::getLoader($engine, $loaderClass);
            $resourceLoader->init($loaderConfiguration, $engine);
            
            $this->resourceLoaders[$resourceLoaderName] = $resourceLoader;
    	}
    	
    	/*
    	 * Check if there is at least one resource loader
    	 */
    	if (! count($this->resourceLoaders)) 
    	{
    		throw new GeryIntializationException("ResourceManager: No resource loaders are found");
    	}
    	
    	/*
    	 * Set the default loader
    	 */
    	$defaultLoaderName = $engine->getConfiguration()->getString("resource.loader.default");
    	
    	if (! strlen($defaultLoaderName))
    	{
    		if (key_exists($defaultLoaderName, $this->resourceLoaders)) 
    		{
    			$this->defaultResourceLoader = $this->resourceLoaders[$defaultLoaderName];
    		} 
    		else 
    		{
    			/*
    			 * Default resource loader not found, using the first defined loader as the default loader
    			 */
    			$loaderKeys = array_keys($this->resourceLoaders);
    			$this->defaultResourceLoader = $this->resourceLoaders[$loaderKeys[0]];
    			
    			
    			$engine->error("Unable to find default resource loader '" . $defaultLoaderName . "', using\n"
                               . get_class($this->defaultResourceLoader) . " as the default resource loader.\n"
                               . "Please adjust configuration");
    		}
    	} 
    	else 
    	{
			/*
			 * No default resource loader set, using the first defined loader
			 */
			$loaderKeys = array_keys($this->resourceLoaders);
			$this->defaultResourceLoader = $this->resourceLoaders[$loaderKeys[0]];
    	}
    	
    	$engine->info("ResourceManager: initialization complete.");
    }
    
	/**
	 * Get a resource
	 *
	 * @throws GeryResourceNotFoundException
	 * @param string $name
	 * @return Resource
	 */
	public function getResource($resourceUrl) {
		
		$resourceLoader = null;
		
		/*
		 * Check whether this is a url with a scheme
		 */
		if (preg_match('/^([a-z]+):\/\/(.+)$/', $resourceUrl, $match)) {
			
			$scheme = $match[1];
			$resourceName = $match[2];
			
			// find the resource loader for this scheme
			foreach ($this->resourceLoaders as $testResourceLoader) 
			{
				if ($testResourceLoader->getScheme() == $scheme) 
				{
					$resourceLoader = $testResourceLoader;
					break;
				}
			}
		}
		// no scheme supplied, use the default resource loader 
		else 
		{
			$resourceLoader = $this->defaultResourceLoader;
			$resourceName = $resourceUrl;
		}
		
		/*
		 * If no resource loader found
		 */
		if ($resourceLoader == null) 
		{
			throw new GeryResourceNotFoundException("No resource loader found for scheme '" . $scheme . "'.");
		}
	
		$resource = $resourceLoader->getResource($resourceName);
		return $resource;
	}
}
?>